查看原文
其他

如何高效的做到全栈数据工程师系列

The following article is from 憋七工作室 Author 憋七

导读:如何高效的做到全栈数据工程师,本文从面试的视角展开主要分为以下篇章:


  1. 数仓动力篇

  2. Hive函数篇

  3. Hive优化篇

  4. 数仓模型篇

  5. 数仓面试篇


☞ 关注公众号『数据仓库与Python大数据』,获取更多优质资源与干货文章

作者: 憋七

编辑: 紫霞仙子





正文



一、动力篇


本人三本毕业学生一名,不会java,其余全自学,从事数据仓库工程师6年,现在在一家知名互联网独角兽公司。

对于公司来说,我们这类人就是一个辛勤的小蜜蜂,公司就是我们的家,每天都在为蜂巢不断扩大献出自己的一份力。
 
当然每个公司都不一样,每个公司也都有吐槽的点,在一家互联网公司呆久了受内部因素影响,难免会面临无法与时俱进,跟不上潮流的处境。每只蜜蜂也都有自己的梦想和人生规划,想要提升自己,还有一种途径就是出去面试。
        
作者是个土生土长的二环里北京人,也想说面试请不要地域歧视,每个人都是个体。
        
我亲身经历了10个"蜂巢"面试,以及与同行间沟通,都是如今的大厂或者各行各业的独角兽公司。
        
这个系列我起的标题《如何高效的做到全栈数据工程师》,原因是应了一句话:“面试造核弹,入职拧螺丝”,面试过程问什么的都有,包括前端的实现方式和架构。

写这个系列一方面是从面试中了解到自己不足,其次了解现在市面对数仓工程师工作内容的定义,要学无止境。也希望能帮助到有需要的人,每篇章都不长,我认为是实打实的干货了。但沟通能力和个人情商还是需要自己在工作和生活中自学成长的。
        
经过这10次打击之后,发现数据仓库职业前景一片光明。
        
都说上帝为你关上一扇门就会为你打开一扇窗。我的这一扇窗就是抗击打能力强,10次的打击让我清楚的认识到自己可能根本不是做这一块儿的料。老话说的好:活人不能被尿憋死。

但我还是不甘心,想再憋一憋,至少不想白费这6年的努力,和熬过的夜,和睡过的公司。
        
目前只列举了这些问题,后面系列专题中只介绍面试中遇到的问题,如果我解释不到位的地方,希望大佬能给一些指点,同样后续再有面试新的知识点,会在后续系列中补充。欢迎大佬进群一起讨论:快来加入数据交流群
       
首先入门法宝,从事数据仓库工程师,强烈推荐两本必读书:《数据仓库工具箱》、《大数据之路》
【福利】520当当网全场5折,每满100减50,满200-100,优惠码、折上折减30,170=400!!

二、Hive函数篇


面试函数一定会问到,里面所列举的函数要背下来!需要默写,即使实际用不到,也要了解每个函数的作用,以及思考在不用函数的情况下用SQL如何满足函数同样的效果,一定要亲自拿着数据去执行一次!

窗口函数

  1. row_number()over(partition by order by ):从1开始按照partition by 字段进行排序
  2. rank()over(partition by order by ):从1开始按照partition by 字段排序,遇到并列取相同数值,后面的跳跃计数
  3. dense_rank()over(partition by order by ):从1开始按照partition by 字段排序,遇到并列取相同数值,后面的顺序计数
  4. sum()over(partition by order by #rows between unbounded preceding and current row):根据某列进行汇总,常用在算累计销售额或者累计订单量,#之后的rows between unbounded preceding and current row代表累计增加之前的行,可加可不加
  5. lead(col,n,default)over(partition by order by ):col字段向上n行,default为向上为NULL时的默认值
  6. lag(col,n,default)over(partition by order by):col字段向下n行,default为向下为NULL时的默认值
  7. first_value(col)over(partition by order by):分组排序后,组内的第一个col的值
  8. last_value(col)over(partition by order by):分组排序后,组内的最后一个col的值

UDF、UDAF、UDTF


Hive的SQL还可以通过用户定义的函数(UDF),用户定义的聚合(UDAF)和用户定义的表函数(UDTF)进行扩展。


当Hive提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数(UDF)

UDF、UDAF、UDTF的区别:


  • UDF(User-Defined-Function)一进一出

  • UDAF聚合函数(User-Defined Aggregation Funcation)多进一出,如count(),sum()

  • UDTF制表函数(User-Defined Table-Generating Functions)一进多出,如 lateral view explore()


4种排序

  1. order by:全局排序,缺点是会把分组的数据放到一个Reduce中

  2. sort by:局部排序,把每个Reduce中的数据进行排序,Reduce数量在2个以上有用,缺点是输出排序结果会有重叠

  3. distribute by:提前排序,在Map端先进行排序,再结合sort by,把排好序的数据放到同一个Reduce中再进行局部排序,如同group by,放在sort by之前,例如:select * from A group by col distribute by time sort by id

  4. cluster by:如果distribute by和sort by 的字段相同,就可以用cluster by代替他们的组合用法,缺点是只能升序,不能asc和desc,而且只能保证一个分区内的排序,例如:select * from A cluster by id (同select * from A distribute by id sort by id)


行转列、列转行
列转行:
  1. concat_ws(',',collect_set(col)):collect_list 不去重,collect_set 去重。col的数据类型要求是string

  2. union all/union


行转列:
  1. lateral view explode(split(col,',')) 虚拟表别名 as 列别名:用法很特殊,放在from tablename和where中间,原理是lateral view(侧视图)与UDTF函数将一行拆分为多行,创建一个虚拟表,再与原表进行笛卡尔积关联。explode()是专门处理map/array结构数据的,解析json数据要配合get_json_object()

  2. case when...end


hive去重方式
  1. group by

  2. distinct

  3. row_number()


这些是SQL基础,也是在实际中出场率算比较高的了,一定要背下来,再偏门的问到也只能说运气不好了。


三、Hive优化篇


每次面试都要问到的,Hive-SQL优化流程,以及引申出来优化问题。数据仓库工程师对接的人各不相同,所以我认为会从两个角度进行优化考虑。


业务人员


从业务方拿到SQL,业务方可能是分析师也可能是产品,但对于SQL底层的了解都是很少的,写的SQL问题很多是会数据倾斜,或者跑不出来的情况,想要解决的第一点就是了解业务!从业务的代码中了解业务过程,再用自己的方式对业务代码进行分层处理加工,但如果自己重新写的话需要评估效率。


1. 笛卡尔积或者order by
造成笛卡尔积的原因就是多对多的关联,解决的话也很简单,了解业务表提前进行汇总达到一对一或者一对多的关联关系,数据量小的话笛卡尔积会造成结果数据不准;业务同学喜欢用order by ,但无论设置多少reduce个数,order by 最后只会生成一个reduce,数据量大的情况笛卡尔积和order by 都会造成OOM


2. count(distinct)
重点:面试都会问到count(distinct)优化,一般都会先问mapreduce的工作原理,再引出这个问题,工作原理在MapReduce篇有介绍,这里会解释下count(distinct)中有key和没key的区别以及count(distinct)一个字段和两个字段的区别,一个字段的话并且有key的情况是和group by 没区别的,如果没key,count(distinct)只会生成一个reduce,造成数据倾斜,但是如果有Key的情况,count(distinct)多个字段,则会采用hash去重方式,容易造成OOM


3. 维度分布不均
key分布不均,会造成数据倾斜,用concat(key,rand())把维度拆分成若干份,再group by统计


4. 谓词下推
大家可以看看下面的两段SQL问题差异在哪里:
这里引出一个概念就是,on的优先级大于where,所以B存在的问题是先将A和B底层所有数据全部取出后再进行where 的过滤,会极大降低执行效率,更有可能出现跑不出数的情况


5. select *
禁止使用select *,因为使用表中的字段无法直观的找到对应关系,以及逻辑依赖,第二个是mapreduce底层计算时避免引用无用的字段,造成资源浪费


6. semi join
被问到了两次,A left semi join B :B表过滤A表数据,但不显示B表,代替的是in/exists 子查询的情况,效率快的原因是semi join只在map阶段过滤,所以过滤条件都要在on 后限制。还有一个特点是B表若有重复数据,A表直接跳过,因此也会省去一部分查询时间。

数仓工程师


从工程师自身角度,对于优化,要看的问题是偏底层的。


1. 小文件过多  
文件自身问题、动态分区插入数据和Reduce任务过多,会生成很多的小文件。下游再依赖小文件过多的任务,再生成更多的小文件,恶性循环,map会从hdfs中拿数据,文件过多,map task就会很多,JobTrack监控Map task任务,小文件过多会造成NameNode的资源压力过大,执行时也会浪费大量资源、影响执行效率。
解决办法有很多种:先执行一次任务,查看数据大小,再根据hadoop块大小推算出需要有多少个reduce数量
  • 在map端做合并:hive.merge.mapfiles=true(默认值为true)
  • 在reduce端做合并:hive.merge.mapredfiles=false(默认值为false)
  • 合并文件大小:hive.merge.size.per.task=256*1000*1000(默认值为256000000)
  • 减少Textfile文件格式存储
  • 使用参数减少Reduce数量:set mapred.reduce.tasks=n
  • hadoop archive命令把小文件进行归档

        

2. JVM 重用 
JVM和job有关,JVM重用也是提高效率的手段之一
可使用参数:mapred.job.reuse.jvm.num.tasks


3.更多可参考:Hive性能优化(全面)



四、数仓模型篇


数据仓库工程师以离线数仓为核心,现在实时数仓也是大势所趋、必备技能!面试主要说自己和公司数仓的关系和承担角色,数仓建设的时间轴,分层情况,以及每层的功能用途。


用语言将离线+实时数仓的架构图描绘清楚,这个考点基本是考是否真的做过数仓体系。最重要的是要抽象业务,围绕业务去聊设计理念。


描绘完毕后基本会被问到几个问题:

数据接入


建模过程


有人说“数仓建模是毫无技术门槛的”,似乎也是那么个道理,概念性很强,但真正掌握的同学好像并不多,重点是还要结合公司自身业务。


我也不懂现在为什么在面试数据仓库的时候,都不关心仓库使用情况,面试官只关心你设计的和面试官脑中的是否一致。如果不一致说明就是瞎设计,曾经某壳的面试官在面试结束后说:“建议你看看什么是维度建模!”


因此引出Kimball和Inmon的两种模型:


  1. Inmon

自上而下设计理念,从业务需求为出发点,基本没人用,但对于刚搭建数据仓库的公司非常适用,开发快,但维护成本高,并不能叫真正意义上的数据仓库。


    2.Kimball

维度模型,自下而上,开发慢,维护成本低,如今真正意义的数据仓库,避免烟斗式开发,对平台衍生系统给予更好的支持和管理


  • 退化维度:把维度信息放到事实表中,一般都是事务的编号,如订单编号、发票编号等。这类编号需要保存到事实表中,但是不需要对应的维度表,所以称为退化维度。


  • Kimball中三个重要的概念:一致性维度、一致性事实、总线架构。这里的总线架构的概念需要明白,有些面试官会用这些专业名词考察你的理论知识


  • 总线架构:就是多维体系架构,还要用到一致性维度概念,可以理解成不同的业务线使用相同的数据维度,就叫总线架构。引入一个网图更好理解:图中四个业务过程用相同的日期,其他指标有相同的也有不同的。



总结延伸


上面两种都是死概念,重点是要根据业务进行改造,考查更多的是抽象业务能力,又如何考察仓库设计的好坏:报表使用情况、报表依赖次数、报表使用资源。这里也牵扯很多问题,例如指标统一、用户画像 等等 ,都是数仓的衍生功能。所以用户画像和指标统一做的好坏也可以一方面反映数仓的建设好坏。


现在又要兴IOT的架构,不了解的同学可移步:Lambda架构已死,去ETL化的IOTA才是未来。我们也尝试过,各方面确实不错,但不适用于国内。国内用IOT架构做数仓是真的没有,但国外可能很成熟了。我想说不要用概念捆绑自己思想,想要进步还是需要勇于创新的。

上层输出


应用层考虑数据输出到哪些产品?(内部业务系统、BI报表、多维系统、用户画像、推荐系统 等等)
以什么方式提供?(Mysql、Tidb、ES、kafka、mq、Hbase、Kylin 等等)



五、面试题篇


给大家也简单总结一下每个面试的知识域,我面试的数据仓库工程师岗位,只罗列所问到的,但不代表每个都问:


  1. 离线数仓分层情况、建模理论以及维度表的概念
  2. 实时数仓是否使用过,如何选型,遇到的问题,业务场景
  3. 数据结构是否了解
  4. Hadoop原理、或分布式原理(问这个问题的面试官竟然不知道CDH是什么)
  5. MapReduce原理
  6. HiveSql优化
  7. Hive函数的使用,排序的区别,行转列,列转行
  8. Mysql引擎以及索引的理解
  9. A/B Test平台、用户画像,设计方法
  10. 算法题
  11. Python语法的理解
  12. 后台开发,工程开发
  13. 当场给业务场景进行设计分层
  14. 元数据系统、数据质量、血缘关系,怎么做的
  15. 打点数据统计、数据埋点管理
  16. Spark原理以及在使用中的问题
  17. 项目管理问题
  18. 外部产品原理(kylin、Tidb、Doris、Airflow等等)


还想和现在找工作的朋友们说一下,很多招聘的职位并不是真的招人,拿着招聘的幌子了解技术架构的也存在不少。所以大家要了解岗位情况和招聘部门情况再做简历推送,不然会耽误很多时间,造成各方面损失。

最后,对于面试经验,再奉上两位一线大厂大佬的面经:

面试系列 | 大厂数据开发面试经验

记一次数据岗位大厂面试(已斩offer)


本篇只是基于个人情况和见闻,我这种普通人的经验可能不适用于大牛和大佬。欢迎入群交流,戳:快来加入数据交流群吧


如有不周,还望指点。

胡言呓语,一笑便罢。

如果您喜欢本文,欢迎点击右上角,把文章分享到朋友圈~~


520当当网全场5折,每满100减50,满200-100,优惠码、折上折减30,170=400!!


Maxwell和Canal的选型和规划


菜鸟实时数仓技术架构演进


基于Binlog实时同步数据仓库问题总结


欢迎加入中台|数仓技术交流群。戳:数据交流群


进群方式:请加微信(微信号:iom1128),回复:数据,通过审核会自动拉你进群。


(备注:行业-职位-城市)


▼ 福利时刻 ▼ 


01. 后台回复「经典」,即可领取大数据数仓经典书籍。

02. 后台回复「中台」,即可领取大厂中台架构高清ppt。

03. 后台回复「加群」,或添加小助微信IDiom1128  拉您入群(大数据|数仓|分析|Flink|资源)或领取资料。


Q: 关于数据仓库,你还想了解什么?


欢迎大家扫描下方二维码订阅「数据仓库与Python大数据」内容并推荐给更多数据方向的朋友,希望有更多机会和大家交流。


更多精彩,请戳"阅读原文"到"数仓之路"查看

  

关注不迷路~ 各种福利、资源定期分享


你也「在看」吗?👇

戳原文,更有料!

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存